@file:Suppress("unused")

package com.hua.giftool.net.api

import com.hua.giftool.BuildConfig
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit

internal const val PROJECT_REMOTE_LOCATION = "https://gitee.com/miaomiaonya/shao-mao-gif/"

object RequestManager {

    /**
     * An interceptor to add custom headers to requests.
     */
    object HeaderInterceptor : Interceptor {
        private val headers = ConcurrentHashMap<String, String>()

        fun addHeader(key: String, value: String) {
            headers[key] = value
        }

        fun removeHeader(key: String) {
            headers.remove(key)
        }

        override fun intercept(chain: Interceptor.Chain): Response {
            val requestBuilder = chain.request().newBuilder()
            headers.forEach { (key, value) ->
                requestBuilder.addHeader(key, value)
            }
            return chain.proceed(requestBuilder.build())
        }
    }

    private val client by lazy {
        val builder = OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .addInterceptor(HeaderInterceptor)

        if (BuildConfig.DEBUG) {
            val loggingInterceptor = HttpLoggingInterceptor()
            loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
            builder.addInterceptor(loggingInterceptor)
        }

        builder.build()
    }

    private val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(PROJECT_REMOTE_LOCATION)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    val apiService: ApiService by lazy {
        retrofit.create(ApiService::class.java)
    }

    /**
     * Executes a suspend function that makes an API call and wraps the result in an [ApiResult].
     *
     * @param T The type of the successful response data.
     * @param apiCall The suspend function to execute.
     * @return An [ApiResult] representing the outcome of the API call.
     */
    suspend fun <T> execute(apiCall: suspend () -> T): ApiResult<T> {
        return try {
            ApiResult.Success(apiCall())
        } catch (e: retrofit2.HttpException) {
            ApiResult.Error(e.code(), e.message())
        } catch (e: IOException) {
            ApiResult.Exception(e)
        }
    }

    fun addHeader(key: String, value: String) {
        HeaderInterceptor.addHeader(key, value)
    }

    fun removeHeader(key: String) {
        HeaderInterceptor.removeHeader(key)
    }
}
